home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
hgraphic.zip
/
GRAPHICS.C
< prev
next >
Wrap
Text File
|
1988-04-12
|
20KB
|
637 lines
/*****************************************************************************/
/* Hercules Compatible graphics routines written for Microsoft Quick C */
/* version 1.0. Compile with large model (option /AL). */
/* */
/* Written by: Ben Bederson (c) 1988 */
/* bbb7889@acf5.NYU.EDU */
/* */
/* 222 East 19th St. #3H */
/* New York, NY 10003 */
/* (212) 260-2667 */
/* */
/* These routines were written by myself for my own purposes and I make */
/* no guarantees, warentees, expressed, or implied, etc. However, */
/* I hope they are useful. Everybody is free and encouraged to copy */
/* and use these routines under the condition that this statement is */
/* kept at the top without modification. I would appreciate any */
/* comments or criticisms or improvement/ideas about these routines. */
/* */
/* Good luck. */
/*****************************************************************************/
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <dos.h>
#include "graphics.h"
/*****************************************************************************/
/* */
/* Routines in this file: */
/* */
/* graphics() - Enter monochrome 720x348 graphics mode (clear scn) */
/* text() - Enter text mode */
/* cls() - Clear the text screen */
/* grcls() - Clear the graphics screen */
/* fill_screen() - Fill the graphics screen to white */
/* dot(x,y,color) - Put a dot of color WHITE,BLACK, or XOR */
/* at the location x,y on the graphics screen */
/* line(x1,y1,x2,y2,color) */
/* - Draw a line from x1,y1 to x2,y2 in color */
/* draw(shape,x,y,color) */
/* - Draw the shape as specified by a */
/* shape_type structure in the specified */
/* color at the specified location x,y. */
/* Not too fast. Try draw_block for some */
/* really fast drawing. */
/* draw_block(shape,x,y,color) */
/* - Draw the shape as specified by a */
/* shape_type structure in the specified */
/* color at the specified location x,y. */
/* The location must be a byte boundary */
/* as this routine does not shift pixels. */
/* But, it is very fast!!! It will not */
/* give an error if x,y is not a byte */
/* boundary, but will shift the block to */
/* draw it on a byte boundary. (This only */
/* applies to the x-axis. */
/* shift_up(shape,x,y,shift_num) */
/* shift_down(shape,x,y,shift_num) */
/* shift_left(shape,x,y,shift_num) */
/* shift_right(shape,x,y,shift_num) */
/* - Shifts the specified shape at the */
/* specified location by shift_num pixels */
/* in the direction corresponding to the */
/* routine name. Really, just a rectangle */
/* is shifted specified by the size in the */
/* shape. This is relatively slow because */
/* bits have to be shifted from one byte to */
/* the next. */
/* */
/* Note: Currently, only shift_right is implemented. */
/* Either use the block shifts, or it should be */
/* very easy to write shift_up,down, and left as */
/* they are just mirror images of shift_right. */
/* shift_up_block(shape,x,y) */
/* shift_down_block(shape,x,y) */
/* shift_left_block(shape,x,y) */
/* shift_right_block(shape,x,y) */
/* - Shifts the specified shape at the */
/* specified location by 8 pixels in the */
/* direction corresponding to the routine */
/* name. Really, just a rectangle is shifted */
/* specified by the size in the shape. This */
/* is very fast as entire bytes are moved */
/* without worrying about shifting bits. */
/* Note: The shape must start on a byte */
/* boundary, or extra pixels will be moved */
/* with it. */
/* */
/*****************************************************************************/
/*****************************************************************************/
/* */
/* User Info: */
/* ---------- */
/* */
/* struct shape_type */
/* */
/* This structure represents a general shape. x and y contain */
/* the size in bytes of a shape. shape_array is a pointer to */
/* an array that must be allocated by the user. The array is */
/* a two dimensional array of single-byte characters where each */
/* bit describes the shape: 1 ON, and 0 OFF. */
/* */
/* The colors are: */
/* WHITE - Draw with pixels on. */
/* BLACK - Draw with pixels off. */
/* XOR - Draw with pixels opposite state of what they were */
/* OVERWRITE - For drawing shapes, 1's put a pixel on, and */
/* 0's put a pixel off. For other colors, 0's */
/* don't do anything. */
/* */
/*****************************************************************************/
char far* screen = (char far *)0xb0000000;
int gr6845[] = {0x38, 0x2d, 0x30, 0x08, 0x5a, 0x00, 0x57, 0x57, 0x02,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int te6845[] = {0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02,
0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*****************************************************************************/
/* */
/* I enter graphics mode by directly accessing the 6845 graphics */
/* controller chip. I found the register addresses and data by */
/* debugging a sample graphics program that came with my Everex */
/* Hercules compatible graphics card. I have tried them on both */
/* Leading Edge and Five Star computers with Hercules-compatible */
/* graphics cards with 100% success, so I expect that it should */
/* work. */
/* */
/*****************************************************************************/
graphics()
{
int i;
outp(0x3b8,0);
outp(0x3bf,3);
for (i=0; i<18; i++) {
outp(0x3b4,i);
outp(0x3b5,gr6845[i]);
}
outp(0x3b8,6);
grcls();
outp(0x3b8,14);
}
/*****************************************************************************/
/* */
/* Read the comment before about the graphics() routine to find */
/* about this routine. */
/* */
/*****************************************************************************/
text()
{
int i;
union REGS regs;
regs.x.ax = 2;
int86(0x10, ®s, ®s);
outp(0x3bf,0);
outp(0x3b8,0x28);
for (i=0; i<18; i++) {
outp(0x3b4,i);
outp(0x3b5,te6845[i]);
}
cls();
}
/*****************************************************************************/
/* */
/* The graphics memory starts at B000:0000, and very unfortunately */
/* is not mapped as you might expect. Each row is simple. A byte */
/* controls 8 pixels, one bit per pixel, high-order bit controlling */
/* the left-most pixel. This continues sequentially accross the */
/* row. To find the address of the next row, however, is not so */
/* easy. By plotting many points, I finally came upon the algorithm */
/* in the macro byte_addr(x,y) in the graphics.h file. Essentially, */
/* you add 0x2000 to get the next row unless you are greater than */
/* 0x8000 in which case you subtract 0x8000 and add 0x5a. If */
/* anybody understands why the screen was memory mapped in this */
/* crazy way, please tell me. I am